package com.swak.devtools.apidoc.parse.parser;

import java.lang.annotation.Annotation;
import java.lang.reflect.Parameter;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.Map;

import com.swak.annotation.flux.Body;
import com.swak.annotation.flux.Cookie;
import com.swak.annotation.flux.Header;
import com.swak.annotation.flux.Json;
import com.swak.annotation.validate.Valid;
import com.swak.devtools.apidoc.parse.ApiParam;
import com.swak.utils.StringUtils;

/**
 * 参数解析
 * 
 * @author 618lf
 */
public class ParamParser extends AbstractParser {

	private final int index;
	private final String name;
	private final Parameter param;
	private final Map<TypeVariable<?>, Type> paramVariablesMappers;
	private final ApiParam apiParam;

	public ParamParser(int index, String name, Parameter param, Map<TypeVariable<?>, Type> paramVariablesMappers) {
		this.index = index;
		this.name = name;
		this.param = param;
		this.paramVariablesMappers = paramVariablesMappers;
		this.apiParam = new ApiParam();
	}

	public ApiParam parse() {

		// 参数的名称
		apiParam.setIndex(index);
		apiParam.setName(name);

		// 注解
		Annotation[] annotations = param.getAnnotations();
		for (Annotation annotation : annotations) {
			if (annotation instanceof Valid) {
				apiParam.setValidFlag(true);
			} else if (annotation instanceof Body) {
				apiParam.setBodyFlag(true);
			} else if (annotation instanceof Json) {
				apiParam.setJsonFlag(true);
			} else if (annotation instanceof Header) {
				Header anno = (Header) annotation;
				apiParam.setHeaderName(StringUtils.defaultIfBlank(anno.value(), name));
			} else if (annotation instanceof Cookie) {
				Cookie anno = (Cookie) annotation;
				apiParam.setHeaderName(StringUtils.defaultIfBlank(anno.value(), name));
			}
		}

		// 解析的结果
		ParsedClass parsedClass = parseClass(param.getParameterizedType(), param.getType(), this.paramVariablesMappers);
		apiParam.setType(parsedClass.getParam().getClazz().getSimpleName());
		apiParam.setApiClass(parsedClass.getApiClass());
		return apiParam;
	}

	public static ApiParam parse(int index, String name, Parameter param,
			Map<TypeVariable<?>, Type> paramVariablesMappers) {
		return new ParamParser(index, name, param, paramVariablesMappers).parse();
	}
}
